﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SlimDX;
using Gype.UI;

namespace Gype.GUI.Components
{
    public class MenuBar : Component
    {
        internal override void attachedToParent(ItemsControl parent)
        {
            base.attachedToParent(parent);

            mNCToken = parent.extendNCArea(0, 25);
            mParent = parent;
        }

        internal override void AttachedToManager(Manager mgr)
        {
            base.AttachedToManager(mgr);
            mBackgroundBrush = Brush.SolidColorBrush(mGUIManager.Target, ConvertExt.ToColor(0xE05C5C5C));
        }

        internal override void RenderObject()
        {
            if (mParent == null || mGUIManager == null)
                return;

            Vector2 ncArea = mParent.getNCExtent(mNCToken);
            var target = mGUIManager.Target;

            target.FillRectangle(ncArea, new Vector2(mParent.getClientSize().X + 1, 25), mBackgroundBrush);

            Vector2 itemPos = ncArea + new Vector2(5, 3);

            for (int i = 0; i < mMenuItems.Count; ++i)
            {
                mMenuItems[i].DrawItem(itemPos);
                itemPos.X += mMenuItems[i].TextSize.X + 5;
            }
        }

        internal override void RenderTopLevel()
        {

        }

        internal bool IsPopupHit(float x, float y)
        {
            Vector2 ncArea = mParent.getNCExtent(mNCToken);
            System.Drawing.RectangleF popupRect = System.Drawing.RectangleF.Empty;
            if (mItemExpanded != null)
            {
                float startX = 5;
                foreach (var item in mMenuItems)
                {
                    if (item.IsExpanded)
                    {
                        popupRect = new System.Drawing.RectangleF(ncArea.X + startX, ncArea.Y + 23, item.mPopupSize.X, item.mPopupSize.Y + 10);
                        break;
                    }

                    startX += item.TextSize.X + 5;
                }
            }

            return popupRect.Contains(x, y);
        }

        internal override void OnMessage(ControlMessage message)
        {
            base.OnMessage(message);
            switch (message.Message)
            {
                case Win32Native.WM.MOUSEMOVE:
                    {
                        MouseMessage msg = message as MouseMessage;
                        Vector2 ncArea = mParent.getNCExtent(mNCToken);
                        System.Drawing.RectangleF barRect = new System.Drawing.RectangleF(ncArea.X, ncArea.Y, mParent.getClientSize().X, 25);

                        if (IsPopupHit(msg.X, msg.Y) && msg.IsHandled == false)
                        {
                            msg.IsHandled = true;
                        }

                        if (barRect.Contains(msg.X, msg.Y) && msg.IsHandled == false)
                        {
                            msg.IsHandled = true;
                            MenuBarPopup newHover = ItemFromPoint(msg.X - ncArea.X, msg.Y - ncArea.Y);
                            if ((!mIsBarItemPressed || newHover != null) && mItemHover != null && mItemHover != newHover)
                            {
                                mItemHover.IsHovered = false;
                            }

                            if (newHover != null)
                            {
                                if (mItemExpanded != null)
                                    mItemExpanded.IsExpanded = false;
                                newHover.IsHovered = true;
                                newHover.IsExpanded = mIsBarItemPressed;
                                if (mIsBarItemPressed)
                                    mItemExpanded = newHover;
                            }
                            if (mIsBarItemPressed == false)
                                mItemHover = newHover;
                            else if (newHover != null)
                                mItemHover = newHover;
                        }
                        else
                        {
                            if (mItemHover != null && !mIsBarItemPressed)
                                mItemHover.IsHovered = false;
                        }
                    }
                    break;

                case Win32Native.WM.LBUTTONDBLCLK:
                case Win32Native.WM.LBUTTONDOWN:
                    {
                        MouseMessage msg = message as MouseMessage;
                        Vector2 ncArea = mParent.getNCExtent(mNCToken);
                        System.Drawing.RectangleF barRect = new System.Drawing.RectangleF(ncArea.X, ncArea.Y, mParent.getClientSize().X, 25);
                        
                        if (barRect.Contains(msg.X, msg.Y) && msg.IsHandled == false)
                        {
                            msg.IsHandled = true;
                            MenuBarPopup newHover = ItemFromPoint(msg.X - ncArea.X, msg.Y - ncArea.Y);

                            if (mItemExpanded != null && mItemExpanded != newHover)
                                mItemExpanded.IsExpanded = false;

                            if (mItemHover != null && mItemHover != newHover)
                                mItemHover.IsHovered = false;

                            if (newHover != null)
                            {
                                mIsBarItemPressed = true;
                                newHover.IsExpanded = mIsBarItemPressed;
                            }
                            else
                                mIsBarItemPressed = false;

                            mItemExpanded = newHover;
                            mItemHover = newHover;
                        }
                        else
                        {
                            if (IsPopupHit(msg.X, msg.Y) == false)
                            {
                                mIsBarItemPressed = false;
                                if (mItemExpanded != null)
                                {
                                    mItemExpanded.IsExpanded = false;
                                    mItemExpanded = null;
                                }
                                if (mItemHover != null)
                                {
                                    mItemHover.IsHovered = false;
                                    mItemHover = null;
                                }
                            }
                            else
                            {
                                msg.IsHandled = true;
                            }
                        }
                    }
                    break;
            }

            switch(message.Message)
            {
                case Win32Native.WM.MOUSEMOVE:
                case Win32Native.WM.LBUTTONDBLCLK:
                case Win32Native.WM.LBUTTONDOWN:
                case Win32Native.WM.LBUTTONUP:
                    {
                        Vector2 ncArea = mParent.getNCExtent(mNCToken);
                        float curXPos = 5;
                        foreach (var popupItem in mMenuItems)
                        {
                            popupItem.HandleMessage(new Vector2(ncArea.X + curXPos, ncArea.Y), message);
                            curXPos += popupItem.TextSize.X + 5;
                        }
                    }
                    break;
            }
        }

        public MenuBarPopup ItemFromPoint(float x, float y)
        {
            if (y < 3 || y > 23)
                return null;

            float curXPos = 5;
            for (int i = 0; i < mMenuItems.Count; ++i)
            {
                float len = mMenuItems[i].TextSize.X + 2;
                if (curXPos <= x && (curXPos + len) >= x)
                    return mMenuItems[i];

                curXPos += len + 5;
            }

            return null;
        }

        public void AddMenuItem(MenuBarPopup item)
        {
            item.AttachedToBar(this);
            mMenuItems.Add(item);
        }

        private List<MenuBarPopup> mMenuItems = new List<MenuBarPopup>();

        private int mNCToken = 0;
        private ItemsControl mParent = null;
        private Brush mBackgroundBrush;
        private MenuBarPopup mItemHover = null;
        private MenuBarPopup mItemExpanded = null;
        private bool mIsBarItemPressed = false;
    }
}
